﻿using Project5.DAL;
using System.Linq;
using Project5.Models;
using System.Collections.Generic;
using System.Data.Entity;
using System;

namespace Project5.DAL
{
    public class SurveyDAL : ISurveyDAL
    {
        private SurveyDB db = new SurveyDB();


        public List<SurveyModel>  FindAllSurveys()
        {
            return db.Surveys.ToList<SurveyModel>();
        }

        public List<ResponseModel> FindAllResponses()
        {
            return db.Responses.ToList<ResponseModel>();
        }

        public List<ProctorModel> FindAllProctors(int surveyID)
        {
            List<ProctorModel> newList = new List<ProctorModel> { };
            //get all surveys proctiored by user
            foreach (var item in db.Proctors.ToList<ProctorModel>())
            {
                if (item.SurveyID == surveyID)
                {
                    newList.Add(item);
                }
            }

            return newList;
        }

        public List<SurveyModel> FindAllSurveys(string username)
        {
            List<SurveyModel> newList = new List<SurveyModel> { };

            //get all surveys created by user
            foreach (var item in db.Surveys.ToList<SurveyModel>())
            {
                if (item.Originator.Equals(username))
                {
                    newList.Add(item);
                }
            }

            //get all surveys that can be viewed by the user
            foreach (var m in db.Proctors.ToList<ProctorModel>())
            {
                if (m.Name.Equals(username))
                {
                    SurveyModel temp = FindSurvey(m.SurveyID);
                    if (temp != null)
                    {
                        if (temp.Originator.Equals(m.Name))
                            continue;
                        else
                            newList.Add(temp);
                    }
                }
            }
            return newList;
        }

        public List<QuestionModel> FindAllQuestionsEager(int id)
        {
            List<ChoiceModel> choices = db.Choices.ToList<ChoiceModel>();
            // LINQ comprehensive syntax to select all Questions with eager Choice fetching
            var model = from m in db.Questions.Include("Choices")
                        where m.SurveyId == id
                        select m;
            List<ChoiceModel> choiceList = db.Choices.ToList<ChoiceModel>();
            return model.ToList<QuestionModel>();
        }

        public List<QuestionModel> FindAllQuestions()
        {
            return db.Questions.ToList<QuestionModel>();
        }

        public List<QuestionModel> FindAllQuestions(int surveyid)
        {
            List<QuestionModel> questions = new List<QuestionModel> { };
            foreach (var item in db.Questions.ToList<QuestionModel>())
            {
                if (item.SurveyId == surveyid) 
                {
                    questions.Add(item);
                }

            }
            return questions;
        }

        public void DeleteChoice(int id){
            var choice = db.Choices.Find(id);
            db.Choices.Remove(choice);
            db.SaveChanges();
        }

        public void DeleteChoices(List<ChoiceModel> choices)
        {
            int choiceCount = choices.Count;
            for(int i = choiceCount - 1; i > -1; i--)
            {
                db.Choices.Remove(choices[i]);
            }
            db.SaveChanges();
        }

        public SurveyModel Add(SurveyModel model)
        {
            model.createDate = System.DateTime.Now.ToString();
            model = db.Surveys.Add(model);
            db.SaveChanges();
            return model;
        }

        public ResponseModel Add(ResponseModel model)
        {
            model = db.Responses.Add(model);
            db.SaveChanges();
            return model;
        }


        public string RenameSurvey(int id, string newName)
        {
            if ( newName != null && !string.IsNullOrEmpty(newName.Trim()))
            {
                SurveyModel survey = FindSurvey(id);
                survey.Name = newName;
                db.SaveChanges();
            }
            return newName;
        }

        public bool SetMonetized(int id, bool monetizedVal)
        {
            SurveyModel survey = FindSurvey(id);
            survey.Monetized = monetizedVal;
            db.SaveChanges();
            return monetizedVal;
        }

        public void actionSurvey(int id, int newState)
        {
            if (newState >= 0 && newState < 4)
            {
                SurveyModel survey = FindSurvey(id);
                if (newState == 0)
                {
                    survey.activationDate = System.DateTime.Now.ToString();
                }
                else if (newState == 1)
                {
                    survey.closeDate = System.DateTime.Now.ToString();
                }                
                survey.State = newState;
                db.SaveChanges();
            }
        }
        public List<ResponseModel> FindAllResponses(SurveyModel model)
        {
            List<ResponseModel> responses = new List<ResponseModel> { };
            foreach (var item in db.Responses.ToList<ResponseModel>())
            {
                if (item.SurveyId == model.Id)
                {
                    responses.Add(item);
                }

            }
            if (responses.Count == 0)
            {
                return null;
            }
            return responses;
        }

        public QuestionModel Add(QuestionModel qmodel)
        {
            qmodel = db.Questions.Add(qmodel);
            db.SaveChanges();
            if (qmodel.Choices == null)
            {
                List<ChoiceModel> choices = new List<ChoiceModel>();
                qmodel.Choices = choices;
            }
            foreach (ChoiceModel choice in qmodel.Choices)
            {
                choice.QuestionId = qmodel.Id;
            }
            db.SaveChanges();
            return qmodel;
        }

        public bool Update(QuestionModel newModel, QuestionModel oldModel)
        {
            bool updated = false;
            if (oldModel != null)
            {
                oldModel.Question = newModel.Question;
                oldModel.Type = newModel.Type;
                oldModel.Choices = newModel.Choices;
                int rows = db.SaveChanges();
                updated = rows > 0;
            }
            return updated;
        }

        public QuestionModel FindQuestionEager(int id)
        {
            List<ChoiceModel> choices = db.Choices.ToList<ChoiceModel>();
            // LINQ comprehensive syntax to select all Questions with eager Choice fetching
            var model = from m in db.Questions.Include("Choices")
                        where m.Id == id
                        select m;
            return model.First<QuestionModel>();
        }

        public void Delete(QuestionModel qmodel)
        {
            QuestionModel qmod = db.Questions.Find(qmodel.Id);
            if (qmod != null)
            {
                db.Questions.Remove(qmod);
            }
            db.SaveChanges();
        }
        
        public void Delete(int SurveyId)
        {
            SurveyModel survey = db.Surveys.Find(SurveyId);
            if (survey != null)
            {
                db.Surveys.Remove(survey);
            }
            db.SaveChanges();
        }

        public SurveyModel FindSurvey(int id)
        {
            SurveyModel survey = db.Surveys.Find(id);
            return survey;
        }

        public void AddProctor(string name, int id)
        {
            SurveyModel survey = FindSurvey(id);
            ProctorModel psurvey = new ProctorModel
            {
                Name = name,
                SurveyID = id
            };
            db.Proctors.Add(psurvey);
            if (survey.State == 1)
            {
                survey.View = 1;
            }
            else survey.View = 0;
            db.SaveChanges();
        }


        public QuestionModel FindQuestion(int id)
        {
            QuestionModel question = db.Questions.Find(id);
            return question;
        }


        public void DeleteQuestion(int id)
        {
            // TODO: Remove the code to delete choices and add Cascade on Delete to the database tables.
            // The database will do this much more efficiently than the Entity Framework
            QuestionModel qmod = FindQuestionEager(id);
            if (qmod != null)
            {
                // remove choices for multi-choice question
                if (qmod.Type == 2) {
                    foreach (ChoiceModel choice in qmod.Choices.ToList<ChoiceModel>())
                    {
                        db.Choices.Remove(choice);
                    }
                }
                db.Questions.Remove(qmod);
            }
            db.SaveChanges();
        }

        public ResponseModel FindResponseByQuestionAndSessionId(int qid, int sessionId)
        {
            List<ResponseModel> rmodels = FindAllResponses();
            foreach (var item in rmodels)
            {
                if ((item.sessionId == sessionId) && (item.QuestionId == qid))
                    return item;
            }
            return null;
        }

        public ResponseModel FindResponse(int id)
        {
            ResponseModel response = db.Responses.Find(id);
            return response;
        }

        public void updateResponse(ResponseModel rmodel)
        {
            List<ResponseModel> rmodels = FindAllResponses();

            ResponseModel model = FindResponse(rmodel.Id);
            model.Response = rmodel.Response;
            db.SaveChanges();
        }

        public List<PaymentModel> FindAllPaymentInfo()
        {
            return db.PaymentInfo.ToList<PaymentModel>();
        }

        public PaymentModel Add(PaymentModel model, string userName)
        {
            model.userName = userName;
            model = db.PaymentInfo.Add(model);
            db.SaveChanges();
            return model;
        }
        
        public PaymentModel FindPaymentInfo(string username)
        {
            List<PaymentModel> payinfos = FindAllPaymentInfo();
            PaymentModel returnInfo = null;

            foreach (PaymentModel payinfo in payinfos)
            {
                if (payinfo.userName == username)
                {
                    returnInfo = payinfo;
                }
            }
            return returnInfo;
        }
    }   
}